%{
	void countrc(void);
%}

%option noyywrap

eax   "EAX"|"eax"
ax	  "AX"|"ax" 
ah	  "AH"|"ah" 
al	  "AL"|"al" 
ebx	  "EBX"|"ebx"
bx	  "BX"|"bx"
bh	  "BH"|"bh"
bl	  "BL"|"bl"
ecx	  "ECX"|"ecx"
cx	  "CX"|"cx"
ch	  "CH"|"ch" 
cl	  "CL"|"cl"
edx	  "EDX"|"edx"
dx	  "DX"|"dx"
dh	  "DH"|"dh"
dl	  "DL"|"dl" 
esi	  "ESI"|"esi"
si	  "SI"|"si"
edi	  "EDI"|"edi"
di	  "DI"|"di"
ebp	  "EBP"|"ebp"
bp	  "BP"|"bp"
esp	  "ESP"|"esp"
sp	  "SP"|"sp"

jmp   "JMP"|"jmp"
mov   "MOV"|"mov"
add   "ADD"|"add"
inc   "INC"|"inc"
sub   "SUB"|"sub"
ret   "RET"|"ret"
cmp   "CMP"|"cmp"

ja    "ja"|"JA"
jae	  "jae"|"JAE"
jb	  "jb"|"JB"
jbe	  "jbe"|"JBE"
je	  "je"|"JE"
jg	  "jg"|"JG"
jge	  "jge"|"JGE"
jl	  "jl"|"JL"
jle	  "jle"|"JLE"
jna	  "jna"|"JNA"
jnae  "jnae"|"JNAE"
jnb	  "jnb"|"JNB"
jnbe  "jnbe"|"JNBE"
jne	  "jne"|"JNE"
jng	  "jng"|"JNG"
jnge  "jnge"|"JNGE"
jnl	  "jnl"|"JNL"
jnle  "jnle"|"JNLE"
jnz	  "jnz"|"JNZ"

hex_digit        [0-9A-F]
digit            [0-9]
alpha            [a-zA-Z_]
white_space      [ \r\t\n]
num              ("-")?{digit}+
uint             {digit}+
int              "-"{digit}+
hex_uint         {hex_digit}+"h"
hex_int          "-"{hex_digit}+"h"
float            ({num})("."{num}?)
identifier       {alpha}+({digit}|{alpha})*

%%

","             { countrc(); FLEX_PRINT(","); return ','; }
":"             { countrc(); FLEX_PRINT(":"); return ':'; }

{eax}           { countrc(); FLEX_PRINT("EAX"); return EAX; }
{ax}            { countrc(); FLEX_PRINT("AX"); return AX; }
{ah}            { countrc(); FLEX_PRINT("AH"); return AH; }
{al}            { countrc(); FLEX_PRINT("AL"); return AL; }
{ebx}           { countrc(); FLEX_PRINT("EBX"); return EBX; }
{bx}            { countrc(); FLEX_PRINT("BX"); return BX; }
{bh}	 	    { countrc(); FLEX_PRINT("BH"); return BH; }
{bl}	 	    { countrc(); FLEX_PRINT("BL"); return BL; }
{ecx}	 	    { countrc(); FLEX_PRINT("ECX"); return ECX; }
{cx}	 	    { countrc(); FLEX_PRINT("CX"); return CX; }
{ch}            { countrc(); FLEX_PRINT("CH"); return CH;  }
{cl}		    { countrc(); FLEX_PRINT("CL"); return CL; }
{edx}		    { countrc(); FLEX_PRINT("EDX"); return EDX; }
{dx}		    { countrc(); FLEX_PRINT("DX"); return DX; }
{dh}		    { countrc(); FLEX_PRINT("DH"); return DH; }
{dl}            { countrc(); FLEX_PRINT("DL"); return DL; }
{esi}		    { countrc(); FLEX_PRINT("ESI"); return ESI; }
{si}		    { countrc(); FLEX_PRINT("SI"); return SI; }
{edi}		    { countrc(); FLEX_PRINT("EDI"); return EDI; }
{di}		    { countrc(); FLEX_PRINT("DI"); return DI; }
{ebp}           { countrc(); FLEX_PRINT("EBP"); return EBP; }
{bp}            { countrc(); FLEX_PRINT("BP"); return BP; }
{esp}           { countrc(); FLEX_PRINT("ESP"); return ESP; }
{sp}            { countrc(); FLEX_PRINT("SP"); return SP; }

{cmp}           { countrc(); FLEX_PRINT("CMP"); return CMP; }
{jmp}           { countrc(); FLEX_PRINT("JMP"); return JMP; }
{mov}           { countrc(); FLEX_PRINT("MOV"); return MOV; }
{add}           { countrc(); FLEX_PRINT("ADD"); return ADD; }
{inc}           { countrc(); FLEX_PRINT("INC"); return INC; }
{sub}           { countrc(); FLEX_PRINT("SUB"); return SUB; }
{ret}           { countrc(); FLEX_PRINT("RET"); return RET; }

{ja}            { countrc(); FLEX_PRINT("JA"); return JA; }  
{jae}           { countrc(); FLEX_PRINT("JAE"); return JAE; }	
{jb}            { countrc(); FLEX_PRINT("JB"); return JB; }	
{jbe}           { countrc(); FLEX_PRINT("JBE"); return JBE; }	
{je}            { countrc(); FLEX_PRINT("JE"); return JE; }	
{jg}            { countrc(); FLEX_PRINT("JG"); return JG; }	
{jge}           { countrc(); FLEX_PRINT("JGE"); return JGE; }	
{jl}            { countrc(); FLEX_PRINT("JL"); return JL; }	
{jle}           { countrc(); FLEX_PRINT("JLE"); return JLE; }	
{jna}           { countrc(); FLEX_PRINT("JNA"); return JNA; }	
{jnae}          { countrc(); FLEX_PRINT("JNAE"); return JNAE; }
{jnb}           { countrc(); FLEX_PRINT("JNB"); return JNB; }	
{jnbe}          { countrc(); FLEX_PRINT("JNBE"); return JNBE; }
{jne}           { countrc(); FLEX_PRINT("JNE"); return JNE; }	
{jng}           { countrc(); FLEX_PRINT("JNG"); return JNG; }	
{jnge}          { countrc(); FLEX_PRINT("JNGE"); return JNGE; }
{jnl}           { countrc(); FLEX_PRINT("JNL"); return JNL; }	
{jnle}          { countrc(); FLEX_PRINT("JNLE"); return JNLE; }
{jnz}           { countrc(); FLEX_PRINT("JNZ"); return JNZ; }	

"\n"            { countrc(); FLEX_PRINT("'\\n'"); return '\n'; }

{uint}          { countrc(); sscanf(yytext, "%u", &yylval.u); FLEX_PRINT("UINT_CONST (%u)", yylval.u); return UINT_CONST; }
{int}           { countrc(); sscanf(yytext, "%d", &yylval.s); FLEX_PRINT("INT_CONST (%d)", yylval.s); return INT_CONST; }
{hex_uint}      { countrc(); sscanf(yytext, "%X", &yylval.u); FLEX_PRINT("UINT_CONST (%u)", yylval.u); return UINT_CONST; }
{hex_int}       { countrc(); sscanf(yytext, "%X", &yylval.s); FLEX_PRINT("INT_CONST (%d)", yylval.s); return INT_CONST; }
{float}         { countrc(); sscanf(yytext, "%f", &yylval.f); FLEX_PRINT("FLOAT_CONST (%f)", yylval.f); return FLOAT_CONST; }
{identifier}    { countrc(); memcpy(identifierBuff, yytext, (identifierLen = yyleng + 1)); FLEX_PRINT("IDENTIFIER (%s)", yytext); return IDENTIFIER; }

";"[^\n]*       { countrc(); FLEX_PRINT("comment"); /* do nothing */ }
{white_space}   { countrc(); FLEX_PRINT("ws"); /* do nothing */ }
.               { countrc(); yyerror("Illegal input\n"); return 0; }
<<EOF>>         { static int once = 0; countrc(); if (once) { FLEX_PRINT("EOF"); } else { FLEX_PRINT("\\n"); } return once++ ? 0 : '\n'; }

%%

void countrc(void)
{
	const char* p;

	for (p = yytext; *p != '\0'; ++p)
	{
		if (*p == '\n')
			col = 0, ++row;
		else
			++col;
	}
}

void yyerror(const char* s)
{
	printf("Error:%u.%u - %s\n", row, col, s);
}